{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<a href=\"https://colab.research.google.com/drive/1EpokQ8Y_5jIJ7HdixZms81Oqgh2sp7-E?usp=sharing\" target=\"_parent\"><img src=\"https://colab.research.google.com/assets/colab-badge.svg\" alt=\"Open In Colab\"/></a>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# LlamaIndex Cognee GraphRAG Integration\n",
    "\n",
    "Connecting external knowledge to the LLM efficiently and retrieving it  is a key challenge faced by developers. For developers and data scientists, integrating structured and unstructured data into AI workflows often involves multiple tools, complex pipelines, and time-consuming processes.\n",
    "\n",
    "Enter **cognee,** a powerful framework for knowledge and memory management, and LlamaIndex, a versatile data integration library. Together, they enable us to transform  retrieval-augmented generation (RAG) pipelines, into GraphRAG pipelines, streamlining the path from raw data to actionable insights.\n",
    "\n",
    "In this post, we’ll explore a demo that leverages cognee and LlamaIndex to create a knowledge graph from a LlamaIndex document, process it into a meaningful structure, and extract useful insights. By the end, you’ll see how these tools can give you new insights into your data by connecting various data sources in one big semantic layer you can analyze.\n",
    "\n",
    "## RAG - Recap\n",
    "\n",
    "RAG enhances LLMs by integrating external knowledge sources during inference. It does so by turning the data into a vector representation and storing it in a vector store.\n",
    "\n",
    "### Key Benefits of RAG:\n",
    "\n",
    "1. Connecting domain specific data to LLMs\n",
    "2. Cost savings\n",
    "3. Higher accuracy than base LLM\n",
    "\n",
    "However, building a RAG system presents challenges: handling diverse data formats, data updates, creating a robust metadata layer, and mediocre accuracy\n",
    "\n",
    "## Introducing cognee and LlamaIndex more\n",
    "\n",
    "cognee simplifies knowledge and memory management for LLMs, while LlamaIndex facilitates connecting LLMs to structured data sources and enabling agentic  use-cases\n",
    "\n",
    "cognee is inspired by human mind and higer cognitive functions. It mimics ways we construct our mental map of the world and build a semantic understanding of various objects, terms and issues in our everyday lives.\n",
    "\n",
    "cognee brings this approach to code by allowing developers to create  semantic layers that would allow users to store their ontologies which are **a formalised depiction of knowledge** in graphs.\n",
    "\n",
    "This lets you use the knowledge you have about a system connect it to LLMs in a modular way, with best data engineering practices, wide choice of vector and graph stores and various LLMs you can use.\n",
    "\n",
    "Together, they:\n",
    "\n",
    "- Turn unstructured and semi-structured data into a graph/vector representation.\n",
    "- Enable ontology generation for particular domains, making unique graphs for every vertical\n",
    "- Provide a deterministic layer for LLM outputs, ensuring consistency and reliability.\n",
    "\n",
    "## Step-by-Step Demo: Building a RAG System with Cognee and LlamaIndex\n",
    "\n",
    "### 1. Setting Up the Environment\n",
    "\n",
    "Start by importing the required libraries and defining the environment:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "!pip install llama-index-graph-rag-cognee==0.1.3"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import os\n",
    "import asyncio\n",
    "from llama_index.core import Document\n",
    "from llama_index.graph_rag.cognee import CogneeGraphRAG\n",
    "\n",
    "if \"OPENAI_API_KEY\" not in os.environ:\n",
    "    os.environ[\"OPENAI_API_KEY\"] = \"\""
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Ensure you’ve set up your API keys and installed necessary dependencies.\n",
    "\n",
    "### 2. Preparing the Dataset\n",
    "\n",
    "We’ll use a brief profile of an individual as our sample dataset:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "documents = [\n",
    "    Document(\n",
    "        text=\"Jessica Miller, Experienced Sales Manager with a strong track record in driving sales growth and building high-performing teams.\"\n",
    "    ),\n",
    "    Document(\n",
    "        text=\"David Thompson, Creative Graphic Designer with over 8 years of experience in visual design and branding.\"\n",
    "    ),\n",
    "]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 3. Initializing CogneeGraphRAG\n",
    "\n",
    "Instantiate the Cognee framework with configurations for LLM, graph, and database providers:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "cogneeRAG = CogneeGraphRAG(\n",
    "    llm_api_key=os.environ[\"OPENAI_API_KEY\"],\n",
    "    llm_provider=\"openai\",\n",
    "    llm_model=\"gpt-4o-mini\",\n",
    "    graph_db_provider=\"networkx\",\n",
    "    vector_db_provider=\"lancedb\",\n",
    "    relational_db_provider=\"sqlite\",\n",
    "    relational_db_name=\"cognee_db\",\n",
    ")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 4. Adding Data to Cognee\n",
    "\n",
    "Load the dataset into the cognee framework:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "await cogneeRAG.add(documents, \"test\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "This step prepares the data for graph-based processing.\n",
    "\n",
    "### 5. Processing Data into a Knowledge Graph\n",
    "\n",
    "Transform the data into a structured knowledge graph:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "await cogneeRAG.process_data(\"test\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The graph now contains nodes and relationships derived from the dataset, creating a powerful structure for exploration.\n",
    "\n",
    "### 6. Performing Searches\n",
    "\n",
    "### Answer prompt based on knowledge graph approach:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "search_results = await cogneeRAG.search(\n",
    "    \"Tell me who are the people mentioned?\"\n",
    ")\n",
    "\n",
    "print(\"\\n\\nAnswer based on knowledge graph:\\n\")\n",
    "for result in search_results:\n",
    "    print(f\"{result}\\n\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Answer prompt based on RAG approach:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "search_results = await cogneeRAG.rag_search(\n",
    "    \"Tell me who are the people mentioned?\"\n",
    ")\n",
    "\n",
    "print(\"\\n\\nAnswer based on RAG:\\n\")\n",
    "for result in search_results:\n",
    "    print(f\"{result}\\n\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "In conclusion, the results demonstrate a significant advantage of the knowledge graph-based approach (Graphrag) over the RAG approach. Graphrag successfully identified all the mentioned individuals across multiple documents, showcasing its ability to aggregate and infer information from a global context. In contrast, the RAG approach was limited to identifying individuals within a single document due to its chunking-based processing constraints. This highlights Graphrag's superior capability in comprehensively resolving queries that span across a broader corpus of interconnected data."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 7. Finding Related Nodes\n",
    "\n",
    "Explore relationships in the knowledge graph:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "related_nodes = await cogneeRAG.get_related_nodes(\"person\")\n",
    "\n",
    "print(\"\\n\\nRelated nodes are:\\n\")\n",
    "for node in related_nodes:\n",
    "    print(f\"{node}\\n\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Why Choose Cognee and LlamaIndex?\n",
    "\n",
    "### 1. Agentic Framework and Memory tied together\n",
    "\n",
    "Your agents can now get long-term, short-term memory and memory specific to their domains\n",
    "\n",
    "### 2. Enhanced Querying and Insights\n",
    "\n",
    "Your memory can now automatically optimize itself and allow to respond to questions better\n",
    "\n",
    "### 3. Simplified Deployment\n",
    "\n",
    "You can use the standard tools out of the box and get things done without much effort\n",
    "\n",
    "## Visualizing the Knowledge Graph\n",
    "\n",
    "Imagine a graph structure where each node represents a document or entity, and edges indicate relationships.\n",
    "\n",
    "Here’s the visualized knowledge graph from the simple example above:\n",
    "\n",
    "![example.png]()\n",
    "\n",
    "\n",
    "## Conclusion\n",
    "\n",
    "Try running it yourself\n",
    "\n",
    "[join the cognee community](https://discord.gg/tV7pr5XSj7)"
   ]
  }
 ],
 "metadata": {
  "language_info": {
   "name": "python"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
